package com.sc.nft.controller;


import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.*;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.vo.*;
import com.sc.nft.entity.vo.salvageEvents.SalvageEventsPageVO;
import com.sc.nft.entity.vo.salvageEvents.SalvageEventsScreenVO;
import com.sc.nft.entity.vo.salvageEvents.SalvageProductPageVO;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.NftMallService;
import com.sc.nft.service.SalvageEventsDetailsService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/salvage/events")
@Api(tags ="分解活动")
public class SalvageEventsController {

    private final SalvageEventsDetailsService salvageEventsDetailsService;
    private final NftMallService nftMallService;
    private final Redisson redisson;
    @ApiOperation(value = "获取分页分解活动列表", notes = "获取分页分解活动列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageEventsPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<SalvageEventsPageVO> getSalvageEventsPage(@Valid @RequestBody SalvageEventsPageRequest request)  {
        return PageResult.success(salvageEventsDetailsService.getSalvageEventsPage(request.getShowSalvagePrefecture(),request.getPageNo(),request.getPageSize()));
    }


    @ApiOperation(value = "获取分解活动剩余次数", notes = "获取分解活动剩余次数", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageUserCount", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<SalvageUserCountVO> getSalvageUserCount(@Valid @RequestBody IdRequest request)  {
        return Result.success(salvageEventsDetailsService.getSalvageUserCount(UserPool.getUser(),request.getId()));
    }


    @ApiOperation(value = "获取活动的筛选条件", notes = "获取活动的筛选条件", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageEventsScreen", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<List<SalvageEventsScreenVO>> getSalvageEventsScreen(@Valid @RequestBody IdRequest request)  {
        return Result.success(salvageEventsDetailsService.getSalvageEventsScreen(request.getId()));
    }

    @ApiOperation(value = "我的背包", notes = "我的背包", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getUserCollectionBySalvageEventsId", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<UserCollectionBySalvageEventsIdVO> getUserCollectionBySalvageEventsId(@Valid @RequestBody UserCollectionBySalvageEventsIdRequest request)  {
        return PageResult.success(salvageEventsDetailsService.getUserCollectionBySalvageEventsId(request.getId(), UserPool.getUser(),request.getCollectionIds(),request.getPageNo(),request.getPageSize()));
    }


    @ApiOperation(value = "预获取分解奖励", notes = "预获取分解奖励", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageEventsRewards", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<List<GetSalvageEventsRewardsVO>> getSalvageEventsRewards(@Valid @RequestBody PreGetTheDecompositionRewardRequest request)  {
        if(request.getUserCollectionIds().size() == 0){
            return Result.success(Lists.newArrayList());
        }
        return Result.success(salvageEventsDetailsService.getSalvageEventsRewards(request.getId(), UserPool.getUser(),request.getUserCollectionIds()));
    }


    @ApiOperation(value = "分解藏品", notes = "分解藏品", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/salvageUserCollection", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<List<GetSalvageEventsRewardsVO>> salvageUserCollection(@Valid @RequestBody GetSalvageEventsRewardsRequest request)  {
        if(request.getUserCollectionIds().size() == 0){
            return Result.success(Lists.newArrayList());
        }

        UserInfo user = UserPool.getUser();
        if(!StrUtil.equals( request.getDealPwd(),user.getTransactionPassword())){
            return Result.fail(ErrorCode.PASSWORD_ERROR);
        }

        List<GetSalvageEventsRewardsVO> list = Lists.newArrayList();

        RLock lock = redisson.getLock(RedisKeyEnum.SALVAGE_USER_COLLECTION_LOCK.getKey() + request.getId());
        try {
            boolean res = lock.tryLock(10,  TimeUnit.SECONDS);
            if (res) {
                list = salvageEventsDetailsService.salvageUserCollection(request.getId(), user, request.getUserCollectionIds(),request.getCardInfo());
            }else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (GlobalRunTimeException e){
            throw e;
        }
        catch (Exception e) {
            throw new GlobalRunTimeException("系统超时");
        } finally {
            lock.unlock();
        }

        return Result.success(list);
    }


    @ApiOperation(value = "分解藏品记录", notes = "分解藏品记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userSalvageEventsRecords", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<UserSalvageEventsRecordsVO> userSalvageEventsRecords(@Valid @RequestBody PageRequest request){
        return PageResult.success(salvageEventsDetailsService.userSalvageEventsRecords(UserPool.getUser(),request.getPageNo(),request.getPageSize()));
    }


    @ApiOperation(value = "获取分解商品列表", notes = "获取分解商品列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageProductPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<SalvageProductPageVO> getSalvageProductPage(@Valid @RequestBody SalvageEventsPageRequest request) {
        return PageResult.success(nftMallService.getSalvageProductPage(request.getShowSalvagePrefecture(),request.getPageNo(),request.getPageSize()));
    }

    @ApiOperation(value = "获取分解商品详情", notes = "获取分解商品详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSalvageProductDetails", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<ProductDetailsVO> getSalvageProductDetails(@Valid @RequestBody ProductDetailsRequest request) {
        return Result.success(nftMallService.getSalvageProductDetails(request.getProductId(),request.getAppStoreVersion()));
    }



    @ApiOperation(value = "获取门票详情", notes = "获取门票详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getTicketDetails", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<TicketDetailsVO> getTicketDetails() {
        return Result.success(salvageEventsDetailsService.getTicketDetails(UserPool.getUser()));
    }


    @ApiOperation(value = "获取门票记录", notes = "获取门票记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getTicketRecords", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<TicketRecordsVO> getTicketRecords(@Valid @RequestBody PageRequest request) {
        return PageResult.success(salvageEventsDetailsService.getTicketRecords(UserPool.getUser(),request.toMp()));
    }

}
